package helixoide.secondlife.devices;

import helixoide.Config;
import helixoide.hxLog;
import helixoide.users.User;
import helixoide.users.UserManager;
import java.io.*;
import java.net.*;
public class device 
{
	private String uuid, region, location, channel, urlString;
	private UserManager theManagment;
	private URL deviceURL;
	private messageQueue dataQueue;
	private Config serverConfig;
	private String lastNick;//primarily used to check the object nicks to avoid unneeded NICKs and QUITs  
	private User lastUser;//see above
	private double ping;//used to determine if this device is active or not. devices that have a large ping will be removed
	private deviceManager dmanager;
	public device(String url, String uuid, String region, String location, String channel, UserManager managment,Config serverConfig, deviceManager m)
	{
		this.uuid = uuid;
		this.region = region;
		this.location = location;
		this.channel = channel;
		this.theManagment = managment;
		this.urlString = url;
		this.serverConfig = serverConfig;
		this.dmanager = m;
		try
		{
			this.deviceURL = new URL(url);
		}
		catch(MalformedURLException e)
		{
			e.printStackTrace();
			hxLog.write("Device", "I don't haave a taarget (MalformedURLException)");
			System.out.println("I don't haav a taarget");
		}
		this.dataQueue = new messageQueue(this.deviceURL);
		//we are all setup
	}
	public String dump()
	{
		return uuid + "@@" + region + "@@" + location + "@@" + channel + "@@" + urlString;
	}
	//start of the User creation/deletion methods
	public synchronized void createUser(String nick, String uuid,boolean object, String dUUID)//creates a user when it enters chat range
	{
		//(String userName, String nickName, String hostName, String uuid, String Channel, String realName, unreal32 proto)
		User theUser = theManagment.findUser(nick);
		if(theUser!=null)
		{
			hxLog.write("Device","Tried to create new user: Failed user already exists");
		}
		else
		{
			this.theManagment.newUser(nick, this.serverConfig.getOurURL(), uuid, uuid, uuid, this.channel,object,dUUID);
			//yay new user to make
		}
	}
	//user User creation/deletion methods end
	
	//messaging methods start
	
	public synchronized void sayInWorld(String user, String msg)//say chat inworld
	{
		if(msg.startsWith("\u0001ACTION"))
		{
			String[] parts = msg.split("\u0001ACTION",2);
			String[] parts2 = parts[1].split("\u0001",2);
			msg = "/me " + parts2[0]; 
		}
		this.dataQueue.addMsg("PRIVMSG&" + user + "&" + msg);
		//yay message queue ^.^
		
	}
	public synchronized void sendToChannel(String message, String user)//send chat to a channel on IRC
	{
		User theUser = theManagment.findUser(user);
		if(theUser!=null)
		{
			if(theUser.isObject())
			{
				if(this.lastNick.equals(user))
				{
					this.lastUser.say(this.getChannel(),message);
				}
				this.lastUser = theUser;
				this.lastNick = user;
			}
			else
			{
				if(this.lastUser!=null)
				{
					this.theManagment.removeUser(this.lastUser);
				}
				if(theUser.findChannel(this.getChannel())!=-1)
				{
					theUser.say(this.getChannel(),message);
				}
			}
		}
		if(theUser==null)
		{
			//usually we will have an object saying something here
			if(this.lastUser!=null)
			{
				this.theManagment.removeUser(this.lastUser);
			}
			this.createUser(user, this.uuid,true,this.uuid);
			User object = theManagment.findUser(user);//create a shiny new user
			if(object!=null)
			{
				object.say(this.getChannel(),message);//say what needs to be said, nuf said
				this.lastNick = user;
				this.lastUser = object;
			}
			else
			{					
				hxLog.write("device","BrainFuck error: lastUser and object are both null");
			}

		}
	}
	//messaging methods ends
	public void quitAllUsers(String reason)
	{
		User[] theUsers = theManagment.getUsers();
		for(int i = 0; i<theUsers.length;i++)
		{
			if(theUsers[i]!=null)
			{
				
				this.theManagment.removeUser(theUsers[i].getNick(),this.getUUID(),this.getChannel(),reason);
				
			}
		}
	}
	//Start of the get methods
	public String getChannel()//returns the channel this device is set to
	{
		return this.channel;
	}
	public String getURL()
	{
		return this.urlString;
	}
	public String getUUID()
	{
		return this.uuid;
	}
	//End of the Get methods
	
	//device management methods start
	public synchronized void updateURL(String url)
	{
		hxLog.write("Device", "Device " +this.getUUID()+ " with channel " +this.getChannel()+ " is updating its URL to " +url +"\n");
		this.urlString = url;
		try
		{
			this.deviceURL = new URL(this.urlString);
		}
		catch(MalformedURLException e)
		{
			e.printStackTrace();
			hxLog.write("Device", "Error: Could Not Update URL\n");
		}
		this.dataQueue.updateURL(this.urlString);
	}
	public synchronized void updateUsers(String[] nicks, String[] uuids)
	{
		
		User tempUser = null;
		String tempNick = "";
		String tempUUID = "";
		for(int i = 0;i<nicks.length;i++)
		{
			tempNick = nicks[i].trim();
			tempUUID = uuids[i].trim();
			tempUser = this.theManagment.findUser(tempNick);
			if(tempUser == null)
			{
				//user doesn't exist in our systems, make it
				this.createUser(tempNick, tempUUID,false,this.uuid);
				//hxLog.write("Device", "Error: Could Not Update URL\n");
			}
			
		}
		String[] nicksWeHave = this.theManagment.getNicks();
		boolean found = false;
		for(int i = 0;i<nicksWeHave.length;i++)
		{
			found = false;
			for(int j = 0;j<nicks.length;j++)
			{
				if(nicks[j].trim().equals(nicksWeHave[i].trim()))
				{
					found = true;
				}
			}
			if(found==false)
			{
				//this section has been radically restructured, all functionality has been switched to UserManager.removeUser(String nick, String uuid, String channel);
				this.theManagment.removeUser(nicksWeHave[i],this.getUUID(),this.channel,null);
			}
						
		}
	}
	public synchronized void updatePing(double current)
	{
		this.ping = current;
	}
	public synchronized double getlastPing()
	{
		return this.ping;
	}
	public synchronized void delete(String reason)
	{
		hxLog.write("Device", "Device for channel " + this.channel + " is deleting, reason given: " + reason);
		this.quitAllUsers(reason);
		this.dmanager.removeDeviceFromList(this.dmanager.findDevice(this.uuid));
	}
	//This is here because Selig requires very up to date location information for some project
	public synchronized void updateLocation(String location, String region)
	{
		this.region = region;
		this.location = location;
	}
	public synchronized String getRegion()
	{
		return this.region;
	}
	public synchronized String getCoordinates()
	{
		return this.location;
	}
	//device management methods end
	
	

}
